feat(scribe): first wip for Scribe.Lithography#18
Conversation
There was a problem hiding this comment.
Pull request overview
This PR is an initial “lithography” vocabulary pass over Scribe’s Shape DSL: renaming and reframing the authoring API around Stencil → TypeShape → Etch, and renaming the stream join primitive to Prism, while updating tests and adding/refreshing docs to match the new conceptual model.
Changes:
- Replace
Shape/ShapeBuilder.ProjectwithStencil/TypeShape.Etchand update call sites (tests, analyzers, scriptorium generator). - Rename
Relation.Pair/ShapedPairtoPrism.By/ShapedPrismand update dependent code/tests. - Add substantial new DSL documentation (glossary/dsl/gap analysis) and refresh design docs.
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| Scribe/Shapes/TypeShape.cs | Renames ShapeBuilder to TypeShape and Project → Etch; updates fluent return types. |
| Scribe/Shapes/TypeFocus.cs | Adds a new equatable “focus identity” type for matched type rows. |
| Scribe/Shapes/Stencil.cs | Introduces new static entry point replacing Shape.*() factories. |
| Scribe/Shapes/SquiggleAt.cs | Updates XML docs to reference TypeShape primitives. |
| Scribe/Shapes/ShapeEtchContext.cs | Renames projection context/delegate to etch context/delegate. |
| Scribe/Shapes/ShapedPrism.cs | Renames the joined pair record to prism terminology. |
| Scribe/Shapes/ShapeCheck.cs | Updates XML docs to reference TypeShape. |
| Scribe/Shapes/Shape.cs | Removes the old Shape factory entry point. |
| Scribe/Shapes/Shape_T.cs | Renames projection delegate field to etch delegate and updates invocation. |
| Scribe/Shapes/Prism.cs | Renames Relation/PairBuilder APIs to Prism/PrismBuilder and updates category strings. |
| Scribe/Shapes/MemberDiagnosticSpec.cs | Updates XML docs to reference TypeShape. |
| Scribe/Shapes/MemberCheck.cs | Updates XML docs to reference TypeShape. |
| Scribe/Shapes/FixSpec.cs | Updates XML docs to reference TypeShape. |
| Scribe/Shapes/DiagnosticSpec.cs | Updates XML docs to reference TypeShape. |
| Scribe/Scribe.csproj | Updates comment text describing Scriptorium’s target type. |
| Scribe.Tests/Shapes/TypeShapeTests.cs | Renames test class and updates usage to Stencil + .Etch. |
| Scribe.Tests/Shapes/ShapeToProviderTests.cs | Updates generator tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapeSeverityVariantsTests.cs | Updates variant tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapePhase8PrimitivesTests.cs | Updates analyzer/fix tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapePhase8_5Tests.cs | Updates analyzer/fix tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapeFixProviderTests.cs | Updates fix provider tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapeFixAllProviderTests.cs | Updates fix-all tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/ShapeAnalyzerTests.cs | Updates analyzer tests to use .Etch and Stencil. |
| Scribe.Tests/Shapes/PrismTests.cs | Renames and updates join tests to Prism.By/ShapedPrism. |
| Scribe.Tests/Shapes/PrismIncrementalityTests.cs | Updates incrementality tests to track Prism matched stream. |
| Scribe.Tests/Shapes/CacheCorrectnessAnalyzerTests.cs | Updates cache correctness tests to look for .Etch usage. |
| Scribe.Scriptorium/TypeShapeVariantsGenerator.cs | Renames generator and targets TypeShape for variant emission. |
| Scribe.Scriptorium/Scribe.Scriptorium.csproj | Updates package description to reference TypeShape. |
| Scribe.Ink/Shapes/IShapeCustomFix.cs | Updates docs to reference TypeShape member/type custom-fix entry points. |
| Scribe.Ink/Shapes/CacheCorrectnessAnalyzer.cs | Updates analyzer to detect TypeShape.Etch<TModel> instead of Project. |
| docs/glossary.md | Adds a comprehensive DSL vocabulary glossary using the new metaphor. |
| docs/gap-analysis.md | Adds a gap analysis doc (currently references some pre-rename APIs). |
| docs/dsl.md | Adds a DSL overview doc (currently references Shape.*/.Project). |
| docs/design-member-level-shapes.md | Refreshes design doc toward navigable composition (still references Shape.*/.Project in places). |
| .claude/CLAUDE.md | Updates “Compass” doc index to include new DSL docs (minor terminology mismatch remains). |
| public static class Stencil | ||
| { | ||
| /// <summary>Expose a <see cref="TypeShape"/> over <c>class</c> declarations.</summary> | ||
| public static TypeShape ExposeClass() => new(TypeKindFilter.Class); | ||
|
|
||
| /// <summary>Expose a <see cref="TypeShape"/> over <c>record</c> declarations (class form).</summary> |
There was a problem hiding this comment.
Shape was removed in favour of Stencil, but there are still XML doc crefs in the codebase pointing at Shape.* (e.g. Scribe/Shapes/TypeKindFilter.cs), and the repo treats warnings as errors. Those unresolved crefs will fail the build; update the remaining references to Stencil.Expose* (or whatever the intended replacement is).
| /// <summary>Fully-qualified display name of the matched type (interned).</summary> | ||
| public string Fqn { get; } | ||
|
|
||
| /// <summary>Declaration location — the cache-stable breadcrumb used for equality.</summary> | ||
| public LocationInfo? Origin { get; } | ||
|
|
||
| public TypeFocus(INamedTypeSymbol symbol, string fqn, LocationInfo? origin) | ||
| { | ||
| Symbol = symbol; | ||
| Fqn = fqn; | ||
| Origin = origin; |
There was a problem hiding this comment.
The doc comment says Fqn is "interned", but the constructor just assigns the provided string without interning. Either actually intern/canonicalise the value (if that’s required for memory/caching characteristics) or drop the claim so the XML docs remain accurate.
| /// A sealed, etched Shape typed with its model <typeparamref name="TModel"/>. Produced | ||
| /// by <see cref="TypeShape.Etch{TModel}"/>. Materialises into an analyzer, a generator | ||
| /// provider, or a code-fixer via <see cref="ToProvider"/> / <c>ToAnalyzer</c> / | ||
| /// <c>ToInk</c>. |
There was a problem hiding this comment.
The XML docs mention materialising via ToInk, but the public API in the repo is still ShapeInkExtensions.ToFixProvider(...) (and there’s no ToInk symbol to point readers to). Either add the ToInk alias/extension or update the docs to reference ToFixProvider to avoid misleading guidance.
| /// <c>ToInk</c>. | |
| /// <c>ToFixProvider</c>. |
| ### 1. Shape — the query | ||
|
|
||
| A filter-and-projection rooted at a specific focus. The entry point is `Shape.AnyType()`, `Shape.Record()`, or a similar constructor. Every chained call produces a new Shape; nothing mutates in place. | ||
|
|
||
| ```csharp | ||
| Shape<TypeFocus> s = Shape.AnyType().Implementing(KnownFqns.IThing); | ||
| ``` |
There was a problem hiding this comment.
This doc describes the entry point as Shape.AnyType() / Shape.Record() and the terminal as .Project<TModel>(...), but the PR replaces these with Stencil.Expose*() and .Etch<TModel>(...). Update the examples/terminology so the DSL doc matches the current public API.
| ## Status | ||
|
|
||
| The Shape DSL today is strictly type-level: | ||
| What the Shape DSL can already do: | ||
|
|
||
| - `ShapeCheck.Predicate(INamedTypeSymbol, Compilation, CancellationToken) -> bool` — one verdict per type. | ||
| - `SquiggleAt` locates on the type (identifier / keyword / attribute / full decl). | ||
| - `MessageArgs(INamedTypeSymbol) -> EquatableArray<string>` — one message per type. | ||
| - `IShapeFix.FixAsync` receives the `TypeDeclarationSyntax`, not a specific member. | ||
| | Primitive | Status | Notes | | ||
| | --------- | ------ | ----- | | ||
| | Type-level predicates (`MustBePartial`, `MustBeSealed`, `MustBeRecord`, `MustBeReadOnly`, `MustBeRecordStruct`, `MustNotBeNested`, `Implementing`, …) | Shipped | Surface: `Shape.AnyType() / Shape.Record() / …` → fluent chain → `Project<TModel>`. | | ||
| | Projection to equatable model | Shipped | `ShapedSymbol<TModel>` with `Fqn`, `Model`, `Location`, `Violations`. Drives both `ToAnalyzer()` and `ToProvider(context)`. | | ||
| | Member-level rules (`ForEachMember`) | Shipped | `MemberCheck`, `MemberDiagnosticSpec`, `MemberSquiggleAt`, `MemberSquiggleLocator`. Emits zero-or-more diagnostics per type, squiggled at the member. | | ||
| | Fix kinds | Shipped | Twenty-one built-in `FixKind`s covering modifiers, base list, attributes, visibility, constructors. Plus `FixKind.Custom` + Ink's `WithCustomFix(tag, delegate)` for bespoke rewrites. | | ||
| | Stream-to-stream join | Shipped | `Prism.By<TLeft, TRight>` joins two shape streams by string key, surfaces orphan diagnostics (`RequireLeftHasRight`, `WarnOnRightUnused`). | |
There was a problem hiding this comment.
The “Status” table and examples still refer to the old Shape.* entry points and .Project<TModel>(...). In this PR the public API is Stencil.Expose*() + .Etch<TModel>(...) (and TypeShape), so the doc should be updated to match, especially where it labels things as “Shipped”.
| **Measuring the current implementation against the six-word vocabulary (Shape, Focus, Lens, Prism, Projection, Materialisation) and the full Shape DSL vision.** | ||
|
|
||
| **Audience:** anyone doing the work, or deciding what to do next. Pair this with the [glossary](glossary.md) (the vocabulary) and [dsl.md](dsl.md) (the authored surface) and [design-member-level-shapes.md](design-member-level-shapes.md) (the architectural rationale). | ||
|
|
There was a problem hiding this comment.
This gap analysis still uses pre-rename vocabulary and symbols (e.g. ShapeBuilder, Relation.Pair, Project<TModel>). Since the PR introduces TypeShape/Stencil/Prism/Etch, the “current implementation” descriptions should be updated to the new names to avoid sending contributors to non-existent APIs/files.
| | Document | What it covers | | ||
| | --- | --- | | ||
| | [README](../README.md) | Overview, quick start, component table, doc index | | ||
| | [Glossary](../docs/glossary.md) | Canonical definitions of Shape DSL vocabulary (Shape, Focus, Lens, Projection, Violation, Relation) and text-emission primitives | |
There was a problem hiding this comment.
The compass entry for the new glossary says it defines “Relation”, but this PR renames the concept/API to Prism. Update this description (and any other references) to match the current vocabulary so contributors aren’t pointed at the old term.
| | [Glossary](../docs/glossary.md) | Canonical definitions of Shape DSL vocabulary (Shape, Focus, Lens, Projection, Violation, Relation) and text-emission primitives | | |
| | [Glossary](../docs/glossary.md) | Canonical definitions of Shape DSL vocabulary (Shape, Focus, Lens, Projection, Violation, Prism) and text-emission primitives | |
8eeac96 to
1ab289e
Compare
No description provided.